#include <iostream>
#include <thread>

#include "webrtc/examples/webrtc-lib/V4L2ImageCap/include/capture.h"
#include "webrtc/examples/webrtc-lib/V4L2ImageCap/include/cap_types.h"
#include "webrtc/examples/webrtc-client/websocket_client.h"

S_VCBuf _frameBuf = {0};
S_H264EncBuf h264_vbuf = { 0 };

int width = 1280;
int height = 720;

/*
int width_ = 640;
int height_ = 480;
*/
int width_ = 320;
int height_ = 240;

bool stop_capture = false;

bool AllocateVideoBuffers() {
    if (0 == _frameBuf.len || NULL == _frameBuf.buf) {
        _frameBuf.len = (sizeof(uint8_t) * width * height * 3) >> 1;
        uint8_t* pBuf = (uint8_t*)malloc(_frameBuf.len);
        if (NULL == pBuf) {
            return -1;
        }
        _frameBuf.buf = pBuf;
    }

    if ((0 == h264_vbuf.len) || (NULL == h264_vbuf.buf) ) {
        h264_vbuf.len = (sizeof(uint8_t) * width * height * 3) >> 1;
        uint8_t *h264_buf = (uint8_t *)malloc(h264_vbuf.len);
        if (!h264_buf) {
            return -1;
        }

        h264_vbuf.BytesUsed = 0;
        h264_vbuf.buf = h264_buf;
    }
    return true;
}

bool DeAllocateVideoBuffers() {
    if (NULL != _frameBuf.buf) {
        free(_frameBuf.buf);
        _frameBuf.buf = NULL;
        _frameBuf.len = 0;
    }

    if (NULL != h264_vbuf.buf) {
        free(h264_vbuf.buf);
        h264_vbuf.buf = NULL;
        h264_vbuf.len = 0;
    }
    return true;
}

void initializeVideoCapture() {
    int nResult = VideoCapture_Initialize(0, width, height, VIDEO_CAP_FMT_NV21, 0, 0);
    std::cout << nResult << std::endl;
    nResult = VideoCapture_Start();
    std::cout << nResult << std::endl;
    nResult = VideoCapture_H264EncStart(width_, height_, H264_PROFILE_HIGH, 512 * 1024, NULL);
    std::cout << nResult << std::endl;
}

bool CaptureProcess() {
    initializeVideoCapture();
    AllocateVideoBuffers();
    while(!stop_capture) {
        int nResult = VideoCapture_GetFrame(&_frameBuf, 1);
        if (0 == nResult) {
            nResult = VideoCapture_H264GetEncFrame(&h264_vbuf);
            if (0 == nResult) {
                sendFrameToWebrtc((unsigned char*)h264_vbuf.buf, h264_vbuf.BytesUsed, width, height, !!h264_vbuf.IsKeyFrame);
            }
        }
    }
    VideoCapture_Stop();
    VideoCapture_Finalize();
    (void)VideoCapture_H264EncStop();
    DeAllocateVideoBuffers();
    
    return true;
}


int main(int argc, char* argv[]) {
    std::string host = "120.25.60.70";
    std::string port = "3000";
    std::cout << "ENTER websocket-client" << std::endl;
    std::cout << "server = " << host << std::endl;
    std::cout << "port = " << port << std::endl;
    std::thread th(CaptureProcess);
    std::string deviceName = "test1";
    std::string serverAddress = "TODO";
    std::string realDeviceName;
    initializeWebrtc(deviceName, serverAddress, realDeviceName);
    std::cout << "initializeWebrtc over" << std::endl;
    std::this_thread::sleep_for(std::chrono::microseconds(1000000000));
    std::cout << "cleanupWebrtc over" << std::endl;
    // TODO cleanup capture and h264 encode;
    cleanupWebrtc();
    std::cout << "cleanupWebrtc over" << std::endl;
    th.join();
    std::cout << "over" << std::endl;
    return 0;
}
